package com.alex.wechat.component.handler;

import java.util.Date;
import java.util.Map;

import org.apache.commons.lang3.StringUtils;
import org.jeecgframework.web.cgform.common.CgAutoListConstant;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;

import com.alex.wechat.app.config.WxAppContext;
import com.alex.wechat.core.handler.WxAccountType;
import com.alex.wechat.core.handler.WxHandler;
import com.alex.wechat.mp.config.WxConsts;
import com.alex.wechat.mp.message.receive.entity.WxReceiveText;
import com.alex.wechat.mp.message.receive.service.WxReceiveTextServiceI;

import cn.binarywang.wx.miniapp.bean.WxMaKefuMessage;
import me.chanjar.weixin.common.exception.WxErrorException;
import me.chanjar.weixin.component.api.WxCompService;
import me.chanjar.weixin.message.bean.WxXmlMessage;
import me.chanjar.weixin.message.rule.WxMessageHandler;
import me.chanjar.weixin.mp.bean.message.WxMpXmlMessage;
import me.chanjar.weixin.mp.bean.message.WxMpXmlOutMessage;

/**
 * 转发客户消息给客服Handler
 * 
 * @author Debenson
 * @since 0.1
 */
@WxHandler(priority = Integer.MIN_VALUE, accountType = WxAccountType.COMPONENT)
public class CompMsgHandler implements WxMessageHandler {
  private static final Logger logger = LoggerFactory.getLogger(CompMsgHandler.class);

  @Autowired
  private WxReceiveTextServiceI receiveTextService;
  @Autowired
  private WxCompService compService;

  @Override
  public String handle(WxXmlMessage wxMessage, Map<String, Object> context)
      throws WxErrorException {
    if (logger.isDebugEnabled()) {
      logger.debug("开始处理客服消息");
    }

    final String key = wxMessage.getContent();
    if (isDistTestMessage(key)) {
      return processDistTest(wxMessage);
    }

    // 暂时记录下客服消息
    saveReceiveText(wxMessage);

    // 默认回复消息
    WxMpXmlOutMessage m = WxMpXmlOutMessage.TRANSFER_CUSTOMER_SERVICE()
        .fromUser(wxMessage.getToUser()).toUser(wxMessage.getFromUser()).build();
    return m.toXml();
  }

  /**
   * 是否为全网发布测试消息
   * 
   * @param content
   * @return
   */
  private boolean isDistTestMessage(String content) {
    return StringUtils.isNotBlank(content)
        && content.startsWith(WxConsts.COMPONENT_DIST_MSG_TEST_PREFIX);
  }

  /**
   * 微信模推送给第三方平台方：文本消息，其中Content字段的内容固定为：
   * QUERY_AUTH_CODE:$query_auth_code$（query_auth_code会在专用测试公众号自动授权给第三方平台方时，由微信后台推送给开发者）
   * 
   * @param content
   * @return
   */
  private String getQueryAuthorCode(String content) {
    return content.substring(WxConsts.COMPONENT_DIST_MSG_TEST_PREFIX.length());
  }

  /**
   * 模拟粉丝发送文本消息给专用测试小程序，第三方平台方需立即使用客服消息接口发送消息回复粉丝
   * 1）微信模推送给第三方平台方：文本消息，其中Content字段的内容固定为：
   * QUERY_AUTH_CODE:$query_auth_code$（query_auth_code会在专用测试公众号自动授权给第三方平台方时，由微信后台推送给开发者）
   * 
   * 2）第三方平台方拿到$query_auth_code$的值后，通过接口文档页中的“使用授权码换取公众号的授权信息”API，将$query_auth_code$的值赋值给API所需的参数authorization_code。然后，调用发送客服消息api回复文本消息给粉丝，其中文本消息的content字段设为：$query_auth_code$_from_api（其中$query_auth_code$需要替换成推送过来的query_auth_code）
   * 
   * @param wxMessage
   * @return 回复消息
   * @throws WxErrorException
   */
  private String processDistTest(WxXmlMessage wxMessage) throws WxErrorException {
    final String key = wxMessage.getContent();

    // step1
    if (logger.isDebugEnabled()) {
      logger.debug("开始查询授权信息");
    }
    final String queryAuthCode = getQueryAuthorCode(key);

    // step2
    if (logger.isDebugEnabled()) {
      logger.debug("开始回复客服消息");
    }
    WxMaKefuMessage msg = new WxMaKefuMessage();
    msg.setTitle("全网发布测试");
    msg.setToUser(wxMessage.getFromUser());
    msg.setMsgType(WxConsts.CUSTOM_MSG_TEXT);
    msg.setContent(queryAuthCode + "_from_api");
    compService.getMaServiceDelegate().getMaMessageService().sendKefuMsg(msg);
    return WxConsts.SUCCESS_MSG;
  }

  /**
   * 保存接收到的信息
   * 
   * @param msg
   * @return
   */
  private WxReceiveText saveReceiveText(WxMpXmlMessage msg) {
    WxReceiveText recvMsg = new WxReceiveText();
    recvMsg.setContent(msg.getContent());
    recvMsg.setCreateDate(new Date());
    recvMsg.setUpdateDate(new Date());
    recvMsg.setFromUserName(msg.getFromUser());
    recvMsg.setToUserName(msg.getToUser());
    recvMsg.setMsgId(String.valueOf(msg.getMsgId()));
    recvMsg.setMsgType(msg.getMsgType());
    recvMsg.setResponse(CgAutoListConstant.BOOL_FALSE);
    recvMsg.setAccountId(WxAppContext.getOriginalId());
    recvMsg.setEvent(msg.getEvent());
    recvMsg.setEventKey(msg.getEventKey());
    recvMsg.setPictureUrl(msg.getPicUrl());
    recvMsg.setMediaId(msg.getMediaId());
    recvMsg.setThumbMediaId(msg.getThumbMediaId());
    recvMsg.setFormat(msg.getFormat());
    recvMsg.setRecognition(msg.getRecognition());
    recvMsg.setLocationX(msg.getLocationX() == null ? null : msg.getLocationX().toString());
    recvMsg.setLocationY(msg.getLocationY() == null ? null : msg.getLocationY().toString());
    recvMsg.setLocationLabel(msg.getLabel());
    receiveTextService.save(recvMsg);
    return recvMsg;
  }

}
